#include "stdafx.h"
#include "Terrain.h"
#include "..\..\EdgeGraphics\GraphicsManager.h"
#include "..\..\EdgeGraphics\IDrawable.h"
#include "..\..\EdgeGraphics\Model.h"
#include "..\..\EdgeContent\ContentManager.h"
#include "../../EdgeGraphics/SamplerStateManager.h"
#include "Heightmap.h"
#include "../../EdgeGraphics/TextureRegisterManager.h"
#include "../../EdgeGraphics/VertexFormats.h"
#include "../../EdgeGraphics/VertexBuffer.h"
using namespace VertexFormats;

Terrain::Terrain(Heightmap* heightmap)
{
	ContentManager* pContent = ContentManager::GetInstance();
	ID3D11Device* pDevice = GraphicsManager::GetInstance()->getDevice();
	ID3D11DeviceContext* pContext = GraphicsManager::GetInstance()->getDeviceContext();

#if 0
	int vWidth = heightmap->getWidth() / 20;
	int vHeight = heightmap->getHeight() / 20;
	unsigned int numVertecies = vWidth * vHeight;
	VertexNormalTextureTangent* vertecies = new VertexNormalTextureTangent[numVertecies];
	for (unsigned int y = 0; y < vHeight; y++)
	{
		for (unsigned int x = 0; x < vWidth; x++)
		{

			float height = heightmap->GetHeightAt(x, y);
			vertecies[x + y * vWidth] = VertexNormalTextureTangent(Vector3(x, height, y), vector_3::Zero, vector_3::Zero, Vector2((x * 20) / (float)heightmap->getWidth(), (y * 20) / (float)heightmap->getHeight()));
		}
	}

	vector<unsigned int> indicies;

	for (unsigned int y = 0; y < vHeight; y++)
	{
		for (unsigned int x = 0; x < vWidth; x++)

		{
			indicies.push_back(x + (y + 1) * vWidth);
			indicies.push_back(x + y * vWidth);
			indicies.push_back((x + 1) + (y + 1) * vWidth);

			indicies.push_back(x + y * vWidth);
			indicies.push_back((x + 1) + (y + 1) * vWidth);
			indicies.push_back((x + 1) + y * vWidth);
		}
	}

	VertexBuffer* vBuffer = new VertexBuffer(vertecies, &indicies[0], numVertecies, indicies.size(), VERTEX_TYPE_POSITION_TEXCOORD_NORMAL_TANGENT, true);
#else
	VertexBuffer* vBuffer = pContent->LoadVertexBuffer("Content/Models/flat.mdl", true);
	
	VertexNormalTextureTangent* vertecies = new VertexNormalTextureTangent[vBuffer->getVertexCount()];
	vBuffer->getData(vertecies, sizeof(VertexNormalTextureTangent));
	for (unsigned int i = 0; i < vBuffer->getVertexCount(); i++)
	{
		vertecies[i].position.y = heightmap->GetHeightAt(int(vertecies[i].position.x), int(vertecies[i].position.z));
	}
	unsigned int* indexData;
	vBuffer->getIndexData(&indexData);
	for (unsigned int i = 0; i < vBuffer->getIndexCount(); i+= 3)
	{
		VertexNormalTextureTangent* v1 = &vertecies[indexData[i]];
		VertexNormalTextureTangent* v2 = &vertecies[indexData[i + 1]];
		VertexNormalTextureTangent* v3 = &vertecies[indexData[i + 2]];

		Vector3 dir1 = v1->position - v2->position;
		Vector3 dir2 = v1->position - v3->position;
		dir1.Normalize();
		dir2.Normalize();

		Vector3 normal = dir1 ^ dir2;

		v1->normal = v2->normal = v3->normal = normal;
	}
	vBuffer->setData(vertecies, sizeof(VertexNormalTextureTangent));
	delete indexData;
#endif
	
	delete[] vertecies;

	//model = pContent->LoadMdl("Content/Models/flat.mdl");

	model = new Model(vBuffer);
	model->SetMaterial(pContent->LoadMaterial("Content/Textures/grass.mat"));
	model->setShaderContainer(pContent->LoadShaderPair("ADSLightingVertexShader.cso", "ADSLightingPixelShader.cso"));
	this->heightmap = heightmap;	
}

/*virtual*/ Terrain::~Terrain(void)
{
	if (heightmap)
		delete heightmap;
}

/*virtual*/ void Terrain::Update(float dt) /*override*/
{
	// implament base game component
}

/*virtual*/ void Terrain::Draw(void) /*override*/
{
	TextureRegisterManager* trm = TextureRegisterManager::GetInstance();
	SamplerStateManager* ssm = SamplerStateManager::GetInstance();
	

	ssm->setCurrentSamplerState(ssm->samplers.linearWrap, { SHADER_INDEX_PIXEL_SHADER, ALL_TEXTURE_SLOTS });
	GameObject::Draw();
	ssm->setCurrentSamplerState(ssm->samplers.linearClamp, { SHADER_INDEX_PIXEL_SHADER, ALL_TEXTURE_SLOTS });
}


/*static*/ Terrain* Terrain::createFromHeightmap(Heightmap* heightmap)
{
	return nullptr;
}